import { AnyAction, Reducer } from 'redux';
import { EffectsCommandMap } from 'dva';
import { message } from 'antd';
import router from 'umi/router';
import { fetchValidation } from '@/utils';
import {
  queryContractDetail,
  queryPartnersList,
  checkContract,
  queryContractSubjectList,
  queryContractTypeDetail,
  addContract,
  uploadContract,
  queryReimbursement,
  querySaleInfo,
} from './service';

export type Effect = (
  action: AnyAction,
  effects: EffectsCommandMap & {
    select: <T>(func: (state: {}) => T) => T;
  }
) => void;

export interface ModelType {
  namespace: string;
  state: {};
  effects: {
    fetch: Effect;
    fetchPartners: Effect;
    fetchContractType: Effect;
    check: Effect;
    add: Effect;
    fetchReimbursement: Effect;
    upload: Effect;
    fetchTotalM: Effect;
  };
  reducers: {
    save: Reducer;
    AccordingInfo: Reducer;
    import: Reducer;
    alsoMoney: Reducer;
    borrow: Reducer;
    checkNum: Reducer;
    setSale: Reducer;
    clear: Reducer;
  };
}

const defaultData = {
  detail: {},
  partnersAndSubject: {
    partners: [],
    subject: [],
  },
  contractTypeDetail: {},
  borrowing: {},
  reimbursement: [],
  is_contract_num: 0,
  saleInfo: {},
};

const Model: ModelType = {
  namespace: 'franchiseeContractEditor',

  state: defaultData,

  effects: {
    * fetch({ payload }, { call, put }) {
      const detail = yield call(queryContractDetail, payload);
      const data = fetchValidation(detail);
      yield data && put({
        type: 'save',
        payload: detail.body,
      });
    },

    * fetchPartners({ payload }, { call, put }) {
      const partners = yield call(
        queryPartnersList, { ...payload, pageNum: 1, numPerPage: 100000 },
      );
      const subject = yield call(queryContractSubjectList, payload);
      const margeObject = {
        partners: partners.body.list || [],
        subject: subject.body,
      };

      yield put({
        type: 'import',
        payload: margeObject,
      });
    },

    * fetchContractType({ payload }, { call, put }) {
      const response = yield call(queryContractTypeDetail, payload);
      const data = fetchValidation(response);
      yield data && put({
        type: 'check',
        payload: response.body,
      });
      yield data && put({
        type: 'AccordingInfo',
        payload: response.body,
      });
    },

    * check({ payload }, { call, put }) {
      const params = {
        contract_id: payload.fcs_info.id,
        contract_type: payload.contract_type,
        contract_num: payload.contract_num,
      };
      const response = yield call(checkContract, params);
      const data = fetchValidation(response);
      if (data) {
        if (data.body === 0) message.error('合同编号重复，请修改后再提交!');
        yield put({
          type: 'checkNum',
          payload: data.body,
        });
      }
    },

    * add({ payload }, { call, put }) {
      const msg = payload.id ? '更新成功～' : '添加成功~';
      const response = yield call(addContract, payload);
      const data = fetchValidation(response);
      if (data) {
        message.success(msg);
        yield put({
          type: 'global/setPath',
        });
        router.goBack();
      }
    },

    * fetchReimbursement({ payload }, { call, put }) {
      const response = yield call(queryReimbursement, payload);
      const data = fetchValidation(response);
      yield data && put({
        type: 'alsoMoney',
        payload: response.body,
      });
    },

    * upload({ payload }, { call, put }) {
      const response = yield call(uploadContract, payload);
      const data = fetchValidation(response);
      yield data && put({
        type: 'save',
        payload: response,
      });
    },

    * fetchTotalM({ payload }, { call, put }) {
      const response = yield call(querySaleInfo, payload);
      const data = fetchValidation(response);
      yield data && put({
        type: 'setSale',
        payload: response.body,
      });
    },
  },

  reducers: {
    save(state, action) {
      return {
        ...state,
        detail: action.payload,
      };
    },

    AccordingInfo(state, action) {
      return {
        ...state,
        contractTypeDetail: action.payload,
      };
    },

    import(state, action) {
      return {
        ...state,
        partnersAndSubject: action.payload,
      };
    },

    alsoMoney(state, action) {
      return {
        ...state,
        reimbursement: action.payload,
      };
    },

    borrow(state, action) {
      return {
        ...state,
        borrowing: action.payload,
      };
    },

    checkNum(state, { payload }) {
      const value = payload === 1 ? 0 : payload;
      return {
        ...state,
        is_contract_num: value,
      };
    },

    setSale(state, { payload }) {
      return {
        ...state,
        saleInfo: payload,
      };
    },

    clear() {
      return defaultData;
    },
  },
};

export default Model;
